<?php

use app\common\model\AdminUser;
use app\common\model\AdminUserRule;
use app\common\service\AdminToken;
use think\facade\Cookie;


/**
 * 获取admin节点树
 * @param int $fid
 * @param array $selected
 * @param array $parentRules 父级节点(子节点权限继承于父节点)
 * @return array
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function adminRuleTree(int $fid = 0, array $selected = [], array $parentRules = []): array
{
    $data      = [];
    $ruleModel = new AdminUserRule();
    $rs1       = $ruleModel->listMenu($fid, 'all');
    if ($rs1) {
        foreach ($rs1 as $k1 => $v1) {
            //权限判断:没有父节点的、超级管理员、属于父节点的
            if (!isset($parentRules[0]) || (isset($parentRules[0]) && $parentRules[0] == '*') || (isset($parentRules[0]) && in_array($v1['id'], $parentRules))) {
                $item       = [];
                $item['id'] = $v1['id'];
                if ($fid == 0) {
                    $item['spread'] = true;
                }
                $item['title'] = ($v1['type'] == 'menu' ? '📁 ' : '◾ ') . $v1['name'];

                $children = adminRuleTree($v1['id'], $selected, $parentRules);
                if ($children) { //判断是否最终节点
                    $item['children'] = $children;
                } else {
                    if (in_array($v1['id'], $selected)) {
                        $item['checked'] = true;
                    }
                }
                $data[] = $item;
            }
        }
    }
    return $data;
}

/**
 * 生成后台菜单html
 * @param int $fid
 * @param string $class
 * @return array
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function buildMenuHtml(int $fid = 0, string $class = 'layui-nav-item'): string
{
    $adminId = getAdminId();
    if ($adminId <= 0) {
        return '';
    }
    $cackeKey = 'admin:menu_html:fid' . $fid . '_adminid' . getAdminId();
    $html     = \think\facade\Cache::get($cackeKey);
    if (!$html) {
        $rules = getRuleList($adminId);

        $html      = '';
        $ruleModel = new  AdminUserRule();
        $rs1       = $ruleModel->listMenu($fid, 'menu');
        if ($rs1) {
            foreach ($rs1 as $k1 => $v1) {
                if ((isset($rules[0]) && $rules[0] == '*') || in_array(strtolower($v1['rules']), $rules)) {
                    if ($fid == 0) {
                        $html .= '
                <li id="menu' . $v1['id'] . '" class="' . $class . '"><a data-url="' . $v1['rules'] . '" href="javascript:">' . $v1['name'] . '</a>';
                        $html .= buildMenuHtml($v1['id'], 'layui-nav-child');
                        $html .= '</li>
';
                    } else {
                        $html .= '
                <dl id="menu' . $v1['id'] . '" class="' . $class . '"><a href="' . $v1['rules'] . '">' . $v1['name'] . '</a>';
                        $html .= buildMenuHtml($v1['id'], 'layui-nav-child');
                        $html .= '</dl>
';
                    }
                }
            }
        }
        \think\facade\Cache::set($cackeKey, $html);
    }
    return $html;
}

/**
 * 生成后台节点表格
 * @param int $fid
 * @param string $nbsp
 * @return string
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function buildRuleTable(int $fid = 0, $nbsp = '&nbsp;&nbsp;&nbsp;&nbsp;'): string
{
    $html      = '';
    $ruleModel = new AdminUserRule();
    $rs        = $ruleModel->listMenu($fid, 'all');
    if ($rs) {
        foreach ($rs as $k => $item) {
            if ($item['type'] == 'node') {
                $icon       = '◾  '; //'📁 ' : '◾ '
                $addNoteBtn = '';
            } else if ($item['pid'] === 0) {
                $icon       = '📁 ';
                $addNoteBtn = '<i class="layui-icon layui-icon-add-1"></i> 添加节点';
            } else {
                $icon       = '📁 ';
                $addNoteBtn = '<i class="layui-icon layui-icon-add-1"></i> 添加节点';
            }
            $html .= '<tr><td>' . $nbsp . $icon . ' ' . $item['name'] . '</td><td><a  class="editRule" data-id="' . $item['id'] . '" data-id="' . $item['id'] . '" data-name="' . $item['name'] . '"><i class="layui-icon layui-icon-edit"></i> 编辑</a> &nbsp; <a  class="addRule" data-id="' . $item['id'] . '" data-name="' . $item['name'] . '">' . $addNoteBtn . '</a> </td></tr>';
            $html .= buildRuleTable($item['id'], $nbsp . '&nbsp;&nbsp;&nbsp;&nbsp;');
        }
    }
    return $html;
}


/**
 * 生成后台角色表格
 * @param int $fid
 * @param string $nbsp
 * @return string
 */
function buildAdminRoleTable(int $fid = 0, $nbsp = '&nbsp;&nbsp;'): string
{
    $html      = '';
    $roleModel = new \app\common\model\AdminUserRole();
    $rs        = $roleModel->listMenu($fid, 'all');
    if ($rs) {
        foreach ($rs as $k => $item) {
            if ($item['pid'] === 0) {
                $icon = '<i class="layui-icon layui-icon-triangle-r"></i>';
            } else {
                $icon = '<i class="layui-icon layui-icon-right"></i>';
            }
            if ($item['rule_ids'] == '*') {
                $btn = '';
            } else {
                $btn = '<i class="layui-icon layui-icon-edit"></i> 编辑</a> <a  class="selectRule" data-id="' . $item['id'] . '" data-name="' . $item['name'] . '"><i class="layui-icon layui-icon-add-1"></i> 权限</a>';
            }
            $title = rtrim($item['rule_ids'], ',') ? rtrim($item['rule_ids'], ',') : "无";
            $html  .= '<tr><td title="权限节点 ' . $title . '">' . $nbsp . $icon . ' ' . $item['name'] . '</td><td><a  class="editRole" data-id="' . $item['id'] . '">' . $btn . '</td></tr>';
            $html  .= buildAdminRoleTable($item['id'], $nbsp . '&nbsp;&nbsp;');
        }
    }
    return $html;
}

/**
 * 生成角色下拉表单
 *
 * @param integer $fid
 * @param string $nbsp
 * @param int $selectId
 * @return string
 */
function buildRoleSelect(int $fid = 0, string $nbsp = '', int $selectId = 0): string
{
    $html      = '';
    $roleModel = new  \app\common\model\AdminUserRole();
    $rs        = $roleModel->listMenu($fid, 'all');
    if ($rs) {
        foreach ($rs as $k => $item) {
            $html .= ' <option ' . ($selectId == $item['id'] ? ' selected ' : '') . ' value="' . $item['id'] . '">' . ($item['pid'] === 0 ? '' : $nbsp . '├ ') . $item['name'] . '</option>';
            $html .= buildRoleSelect($item['id'], $nbsp . '&nbsp;&nbsp; ', $selectId);
        }
    }
    return $html;
}

/**
 * 获取权限列表
 * @param int $adminId
 * @param int $ttl 缓存有效时间(秒)
 * @return array
 */
function getRuleList(int $adminId, int $ttl = 300): array
{
    $cacheKey = 'admin:rules_' . $adminId;
    $rules    = think\facade\Cache::get($cacheKey);
    //$rules = false;
    if (!$rules) {
        $userModel = new AdminUser();
        $userInfo  = $userModel->where('id', '=', $adminId)->find();
        if (!$userInfo) {
            return [];
        }
        //查找并合并权限节点id
        $roleModel = new  \app\common\model\AdminUserRole();
        $ruleIds   = $roleModel->whereIn('id', rtrim($userInfo['role_ids'], ','))->select();
        $ruleIdArr = [];
        foreach ($ruleIds as $k => $v) {
            $items     = explode(',', rtrim($v['rule_ids'], ','));
            $ruleIdArr = array_merge($ruleIdArr, $items);
        }
        $ruleIdArr = array_unique($ruleIdArr);

        //查找对应的权限
        $ruleModel = new AdminUserRule();

        if (in_array('*', $ruleIdArr)) {
            $rules = ['*'];
        } else {
            $query  = $ruleModel->whereIn('id', implode(',', $ruleIdArr));
            $ruleRs = $query->select();
            $rules  = [];
            foreach ($ruleRs as $k => $v) {
                if (strpos($v['rules'], '://') === false) {
                    $uri = rtrim($v['rules'], '/');
                } else {
                    $uri = $v['rules'];
                }

                $rules[] = strtolower($uri);
            }
        }

        think\facade\Cache::set($cacheKey, $rules, $ttl);
    }
    return $rules;
}

/**
 * 获取当前uri对应的节点id
 * @return array
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function currentRuleId(): array
{
    if (isset(request()->adminUri)) {
        $uri       = request()->adminUri;
        $ruleModel = new AdminUserRule();
        $rs        = $ruleModel->where('rules', '=', $uri)->find();
        if ($rs) {
            return $rs->toArray();
        } else {
            return [];
        }
    }
    return [];
}

/**
 * 获取管理员uid
 * @return int >0=已登录;<=0未登录
 */
function getAdminId(): int
{
    $adminToken = Cookie::get('admin_token');
    if (!$adminToken) {
        return 0;
    }

    $admintokenService = new AdminToken();
    $value             = $admintokenService->getValue($adminToken);
    if (!$value) {
        return -1;
    } else {
        return isset($value['uid']) ? intval($value['uid']) : -2;
    }
}

/**
 * 删除redis缓存
 * @param string $key 支持模糊匹配
 */
function clearRedisCache($key = '')
{
    $redis = initRedis();
    $keys  = $redis->keys($key);
    foreach ($keys as $v) {
        $redis->del($v);
    }
}
